package edu.esiag.isidis.fi.lb.impl;



import java.util.List;


import edu.esiag.isidis.fi.lb.interfaces.IMangerLB;
import edu.esiag.isidis.fi.lb.interfaces.INotifier;
import edu.esiag.isidis.fi.lb.interfaces.IRegister;

public abstract class AbstractManagerLB<EntityType,InformationType> implements IMangerLB<EntityType, InformationType> {
	
	protected INotifier<InformationType> mNotifier;
	protected IRegister<EntityType> mRegister;
	
	
	
	public INotifier<InformationType> getmNotifier() {
		return mNotifier;
	}

	

	public IRegister<EntityType> getmRegister() {
		return mRegister;
	}

	

	public AbstractManagerLB() throws NoEntityException {
		mNotifier = new Notifier<InformationType>();
		mRegister = new Register<EntityType>();
		mNotifier.setLoadBalancer(this);
	}
	
	public EntityType loadBalance(InformationType information) throws NoEntityException{
		List<EntityType>entities=mRegister.getEntities();
		for(int i=0 ; i<entities.size();i++){
			EntityType entity=entities.get(i);
			if(isActivate(entity)){
				if(isBusy(entity))
				{
					return nextEntity(entities,information,i,i+1);
				}
				runProcess(entity,information);
				return entity;
			}
		}
		throw new NoEntityException();
	}
	
	

	private EntityType nextEntity(List<EntityType> entities,InformationType information ,int i, int j) throws NoEntityException {
		if(j==entities.size())
			{
				j=0;
			}
		if(j==i)
			throw new NoEntityException();
		
		EntityType entity=entities.get(j);
		if(isBusy(entity)) return nextEntity(entities,information ,i, j+1);
		
		runProcess(entity, information);
		return entity;
	}
	
	public  void activeEntity(Object id){
		mRegister.activeEntity(id);
	}

	protected abstract void runProcess(EntityType entity, InformationType information);

	protected abstract boolean isBusy(EntityType entity);

	protected abstract boolean isActivate(EntityType entity);
	
	
}
